# Python 类

# 人类
class People:
    hight = "170"  # 在构造方法之外定义属性需要给定默认值

    def __init__(self, name, age):  # Python中的构造方法
        self.name = name  # self 表示当前类的对象 和java中的this 一样
        self.age = age  # 构造方法内部进行定义属性
        self.flag = "人类"
        self.__gender = "女"  # 定义私有属性

    def skill(self):
        print("{}能跑能跳。。。。".format(self.name))


# 创建类对象

people = People("张三", 20)
print(people.age)
print(people.flag)
print(people.name)
print(people._People__gender)  # 私有属性直接调用会报错 但是可以通过_类名私有属性名也可以调用
# 同时也说明 Python中没有严格的封装概念

people.skill()


# 继承
# 语法  class 类名(继承的父类名):
class Teacher(People):

    def __init__(self, name, age, teach):
        super(Teacher, self).__init__(name, age)
        self.teach = teach

    # 子类中的同名函数可以覆盖父类中的函数
    def skill(self):
        print("{}可以教授{}课程".format(self.name, self.teach))


teacher = Teacher("覃老师", 30, "大数据高级课程")
teacher.skill()


# 多态

# :类名 表示指定参数的类型
def run(p: People):
    p.skill()


run(people)
run(teacher)


class Duck():
    def skill(self):
        print("鸭子可以游泳")


# duck中并没有指定其父类为People 但是可以通过创建其对象，然后通过run函数调用其skill方法
# 说明Python中并没有java类似的多态 只要对象中有对应的函数  就可以直接调用
duck = Duck()
run(duck)


# 猴子补丁
# Python中的补丁写法
class Monkey:
    pass


monkey = Monkey()


def skill():
    print("我是一个猴子补丁..")

monkey.skill = skill
run(monkey)


